<template>
  <div class="content">
    <el-row :gutter="20">
      <el-col :span="5">
        <el-affix :offset="70">
          <el-card header="目录" class="grid-content bg-purple-light classify">
            <el-input v-model="filterCatalog" placeholder="请输入"></el-input>
            <el-scrollbar max-height="500px">
              <el-tree
                       :data="catalogTree"
                       :props="defaultProps"
                       @node-click="handleNodeClick"
                       ref="treeRef"
                       :filter-node-method="filterNode"
                       :expand-on-click-node="false"
                       :highlight-current="true"
                       node-key="value"
                       :default-expand-all="ifExpand">
                <template #default="{ node, data }">
                  <el-link :underline="false" :href="'#' + node.label">{{ node.label }}</el-link>
                </template>
              </el-tree>
            </el-scrollbar>
          </el-card>
        </el-affix>
      </el-col>
      <el-col :span="19">
        <el-card>
          <template #header>
            <div class="card-header">
              <span>文章</span>
              <el-button class="button" type="text" :icon="Back" @click="reback">后退</el-button>
            </div>
          </template>
          <md-editor
                     ref="editor"
                     v-model="text"
                     :preview-theme="theme"
                     previewOnly
                     @onGetCatalog="onGetCatalog"></md-editor>
        </el-card>
      </el-col>
    </el-row>
  </div>
</template>

<script lang="ts" setup>
import { onMounted, ref, watch } from 'vue'
import MdEditor from 'md-editor-v3'
import 'md-editor-v3/lib/style.css'
import { Back } from '@element-plus/icons-vue'
import { useRoute, useRouter, onBeforeRouteUpdate } from 'vue-router';
import { getContent } from '@/api/request'
import type { HeadList } from 'md-editor-v3'
import type { Tree } from '@/api/type'
import type { ElTree } from 'element-plus'
import type { TreeOptionProps } from 'element-plus/es/components/tree/src/tree.type'

const text = ref('')
const theme = ref<'vuepress' | 'default' | 'github'>('vuepress')
const treeRef = ref<InstanceType<typeof ElTree>>()

const defaultProps: TreeOptionProps = {
  children: 'children',
  label: 'label',
  class: () => 'customNodeClass'
}

const catalogTree = ref<Tree[]>()

const route = useRoute()
const router = useRouter()

let backStep = -1

onBeforeRouteUpdate((to, from, next) => {
  backStep--
})

const catalogs = ref<HeadList[]>()

const filterCatalog = ref()

const ifExpand = ref(true)

onMounted(async () => {
  const content = await getContent(Number(route.params.articleId))
  text.value = content.content
})

watch(filterCatalog, (val) => {
  treeRef.value!.filter(val)
})

const onGetCatalog = (list: HeadList[]) => {
  const tocItems: Tree[] = []
  catalogs.value = list
  list.forEach(node => {
    const item: Tree = { label: node.text, value: node.level }
    if (tocItems.length === 0) {
      tocItems.push(item)
    } else {
      // 最后一个 item
      let lastItem = tocItems[tocItems.length - 1];
      if (item.value > lastItem.value) {
        for (let i = lastItem.value + 1; i <= 6; i++) {
          // item 是 lastItem 的 children
          const { children } = lastItem;
          if (!children) {
            // 如果 children 不存在
            lastItem.children = [item];
            break;
          }
          // 重置 lastItem 为 children 的最后一个 item
          lastItem = children[children.length - 1];
          if (item.value <= lastItem.value) {
            // item level 小于或等于 lastItem level 都视为与 children 同级
            children.push(item);
            break;
          }
        }
      } else {
        // 置于最顶级
        tocItems.push(item);
      }
    }
  })
  catalogTree.value = tocItems
}

const handleNodeClick = async (data: Tree) => {
}

const filterNode = (value: string, data: any) => {
  if (!value) return true
  return data.label.indexOf(value) !== -1
}

const reback = () => {
  router.go(backStep)
}
</script>

<style lang="less" scoped>
:deep(.customNodeClass) {
  margin: 15px 0px;

  .el-tree-node__label {
    font-size: var(--el-font-size-large);
  }
}
</style>
